package com.qingcloud.adminbackend.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.ImmutableMap;
import com.qingcloud.adminbackend.constant.WamingConstant;
import com.qingcloud.adminbackend.entity.sysorder.SysBusinessApp;
import com.qingcloud.adminbackend.entity.sysorg.SysOrg;
import com.qingcloud.adminbackend.entity.sysorg.SysUserOrg;
import com.qingcloud.adminbackend.entity.user.SysUser;
import com.qingcloud.adminbackend.entity.usergroup.*;
import com.qingcloud.adminbackend.enums.UcRoleEnum;
import com.qingcloud.adminbackend.mapper.*;
import com.qingcloud.adminbackend.mapper.app.UserAppRoleMapper;
import com.qingcloud.adminbackend.service.ISysUsergroupService;
import com.qingcloud.adminbackend.utils.CookieUtil;
import com.qingcloud.base.exception.WamingException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 新用户组 服务实现类
 * </p>
 *
 * @author wangjinnan
 * @since 2018-11-15
 */
@Service
public class SysUsergroupServiceImpl extends ServiceImpl<SysUsergroupMapper, SysUsergroup> implements ISysUsergroupService {

    @Resource
    private SysUsergroupMapper usergroupMapper;

    @Resource
    private SysUsergroupUserMapper usergroupUserMapper;

    @Resource
    private SysUserOrgMgrMapper sysUserOrgMgrMapper;

    @Resource
    private SysUsergroupStationgroupMapper sysUsergroupStationgroupMapper;

    @Resource
    private SysUserMapper sysUserMapper;

    @Resource
    private SysOrgMapper sysOrgMapper;

    @Resource
    private SysUserOrgMapper sysUserOrgMapper;

    @Resource
    private SysBusinessAppMapper businessAppMapper;

    @Resource
    private SysUserRoleMapper sysUserRoleMapper;

    /**
     * 添加用户组
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int add(SysUsergroup sysUsergroup) {
        if (StrUtil.isBlank(sysUsergroup.getOrgId())) {
            SysUserOrg sysUserOrg = sysUserOrgMapper.selectOne(Wrappers.<SysUserOrg>lambdaQuery()
                    .eq(SysUserOrg::getUserId, sysUsergroup.getCreateBy()));
            sysUsergroup.setOrgId(sysUserOrg.getOrgId());
        }
        //保存用户组
        usergroupMapper.insert(sysUsergroup);
        //保存用户组与用户关联
        if (CollUtil.isNotEmpty(sysUsergroup.getUserList())) {
            for (SysUsergroupUser user : sysUsergroup.getUserList()) {
                user.setGroupId(sysUsergroup.getId());
            }
            boolean isChangeOwner = saveUsergroupUser(sysUsergroup.getUserList(), sysUsergroup.getModifyBy());
            if (isChangeOwner) {
                return 1;
            }
        }
        return 0;
    }

    /**
     * 保存用户组用户
     */
    private boolean saveUsergroupUser(List<SysUsergroupUser> userList, String currentUserId) {
        boolean isChangeOwner = false;
        long count = userList.stream()
                .filter(it -> UcRoleEnum.OWNER.code.equals(it.getRoleId()) && !currentUserId.equals(it.getUserId())).count();
        if (count > 1) {
            throw new WamingException("应用只能设置一个拥有者");
        }
        count = userList.stream()
                .filter(it -> UcRoleEnum.OWNER.code.equals(it.getRoleId())).count();
        if (count == 2) {
            isChangeOwner = true;
        }
        for (SysUsergroupUser it : userList) {
            //如果要修改组织管理员，要把当前管理员改成体验者
            if (isChangeOwner && currentUserId.equals(it.getUserId()) && it.getRoleId().equals(UcRoleEnum.OWNER.code)) {
                it.setRoleId(UcRoleEnum.TEST.code);
            }
            if (UcRoleEnum.OWNER.code.equals(it.getRoleId())) {
                //修改应用拥有者
                SysBusinessApp app = businessAppMapper.selectOne(Wrappers.<SysBusinessApp>lambdaQuery().eq(SysBusinessApp::getBizCode, String.valueOf(it.getAppId())));
                app.setOwner(it.getUserId());
                businessAppMapper.updateById(app);
                //老拥有者角色去掉
                usergroupUserMapper.delete(Wrappers.<SysUsergroupUser>lambdaQuery().eq(SysUsergroupUser::getRoleId, UcRoleEnum.OWNER.code)
                        .eq(SysUsergroupUser::getAppId, it.getAppId()));
            }
            usergroupUserMapper.insert(it);
        }
        return isChangeOwner;
    }

    /**
     * 修改用户组
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int modify(SysUsergroup sysUsergroup) {
        boolean isInfo = false;
        if (StrUtil.isBlank(sysUsergroup.getOrgId())) {
            isInfo = true;
            SysUserOrg sysUserOrg = sysUserOrgMapper.selectOne(Wrappers.<SysUserOrg>lambdaQuery()
                    .eq(SysUserOrg::getUserId, sysUsergroup.getModifyBy()));
            sysUsergroup.setOrgId(sysUserOrg.getOrgId());
        }
        //保存用户组
        usergroupMapper.updateById(sysUsergroup);
        //删除用户组和用户关联
        if (!isInfo) {
            usergroupUserMapper.deleteByMap(ImmutableMap.of("group_id", sysUsergroup.getId()));
            //保存用户组与用户关联
            if (CollUtil.isNotEmpty(sysUsergroup.getUserList())) {
                boolean isChangeOwner = saveUsergroupUser(sysUsergroup.getUserList(), sysUsergroup.getModifyBy());
                if (isChangeOwner) {
                    return 1;
                }
            }
        }
        return 0;
    }

    /**
     * 根据用户组ID删除用户组
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteById(String ids) {
        for (String it : ids.split(",")) {
            Long ownerCount = usergroupUserMapper.selectCount(Wrappers.<SysUsergroupUser>lambdaQuery()
                    .eq(SysUsergroupUser::getGroupId, it).eq(SysUsergroupUser::getRoleId, UcRoleEnum.OWNER.code));
            if (ownerCount > 0) {
                throw new WamingException("拥有者所在组不能删除");
            }
            //删除用户组和用户关联
            usergroupUserMapper.deleteByMap(ImmutableMap.of("group_id", it));
            //删除用户组和设备组关联
            sysUsergroupStationgroupMapper.deleteByMap(ImmutableMap.of("usergroup_id", it));
            //删除用户组
            usergroupMapper.logicDeleteById(it);
        }
        return 1;
    }

    /**
     * 分页查询用户组
     *
     * @param param
     * @return
     */
    @Override
    public IPage<SysUsergroupDTO> page(SysUsergroupPageParam param, HttpServletRequest request) {
        //获取登录用户信息
        boolean isAdmin = CookieUtil.isAdmin(request);
        //获取登录用户信息
        String loginUserId = CookieUtil.getUserId(request);
        if (!isAdmin) {
            //不是超级管理员，查看是否有完全管理权限
            SysUser sysUser = sysUserMapper.selectById(loginUserId);
            //完全管理权限这里等同于超级管理员
            if (WamingConstant.ONE.equals(sysUser.getAdminFlag())) {
                isAdmin = true;
            }
        }
        List<String> manageOrgIdList = new ArrayList<>();
        //用户可管理应用列表
        Set<Integer> manageAppId = new HashSet<>();
        //如果不是超级管理员
        if (!isAdmin) {
            //查询当前登录用户可读可写的客户
            List<SysOrg> orgList = sysUserOrgMgrMapper.findAllOrgAndChildByUser(loginUserId, null);
            if (orgList.isEmpty()) {
                return new Page<>();
            }
            List<String> orgIdList = orgList.stream().map(SysOrg::getId).collect(Collectors.toList());
            manageOrgIdList = orgList.stream().filter(it -> WamingConstant.ONE.equals(it.getManage()))
                    .map(SysOrg::getId).collect(Collectors.toList());
            param.setOrgIdList(orgIdList);
            manageAppId = sysUserRoleMapper.findManageAppId(loginUserId);
            if (CollUtil.isEmpty(manageAppId)) {
                return new Page<>();
            }
        }
        //如果用户信息条件不为空，先通过用户信息找到所有用户组
        if (!StringUtils.isEmpty(param.getUserName()) || !StringUtils.isEmpty(param.getMobileno())
                || !StringUtils.isEmpty(param.getFullName())) {
            param.setIdList(usergroupUserMapper.findUserGroupByUser(param.getFullName(), param.getMobileno(),
                    param.getUserName()));
            //没有找到符合条件的用户组ID，则直接返回空
            if (param.getIdList().isEmpty()) {
                return new Page<>();
            }
        }
        //参数条件的组织ID不为空时
        String queryOrgId = param.getOrgId();
        if (!StringUtils.isEmpty(queryOrgId)) {
            List<String> queryOrgIdList = new ArrayList<>();
            SysOrg queryOrg = sysOrgMapper.selectById(queryOrgId);
            //如果是一级客户，要查出分支机构
            if (WamingConstant.ONE.equals(queryOrg.getCategory())) {
                queryOrgIdList = sysOrgMapper.findChildSysOrgListV2(Arrays.asList(queryOrg.getId()))
                        .stream().map(SysOrg::getId).collect(Collectors.toList());
            }
            queryOrgIdList.add(queryOrg.getId());
            param.setOrgIdList(queryOrgIdList);
        }
        IPage<SysUsergroupDTO> page = usergroupMapper.page(param.getPage(), param, manageAppId);
        if (isAdmin) {
            page.getRecords().forEach(it -> it.setManage(1));
        } else {
            List<String> finalManageOrgIdList = manageOrgIdList;
            page.getRecords().stream().filter(it -> finalManageOrgIdList.contains(it.getOrgId()))
                    .forEach(it -> it.setManage(1));
        }
        return page;
    }

    /**
     * 分页查询用户组下成员
     *
     * @param param
     * @return
     */
    @Override
    public IPage<SysUsergroupUserDTO> userPage(SysUsergroupUserParam param) {
        return usergroupUserMapper.page(param.getPage(), param);
    }

    /**
     * 根据客户ID和用户组名称查询用户组
     *
     * @param orgId     客户ID
     * @param groupName 用户组名称
     * @return
     */
    @Override
    public List<SysUsergroupDTO> getUserGroupList(String orgId, String groupName) {
        return usergroupMapper.getUserGroupList(orgId, groupName);
    }

    @Override
    public List<SysUsergroupDTO> getUserGroupByUserId(String userId) {
        return usergroupMapper.getUserGroupByUserId(userId);
    }

    @Override
    public SysUsergroup queryInfo(String id) {
        return usergroupMapper.selectById(id);
    }

}
